package gobelinmaker.server;

import gobelinmaker.data.BasicMotorHoleData;
import gobelinmaker.data.JSONUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;
import org.json.simple.JSONObject;

/**
 * Letapogatott lyukak kezelését megvalósító osztály.
 *
 * @author imruf84
 */
public class ServerHoles {

    /**
     * Munkakönyvtár.
     */
    private final String workingDir;
    /**
     * Oszlopok száma.
     */
    private int columnsCount = 0;

    /**
     * Konstruktor.
     *
     * @param workingDir munkakönyvtár neve
     * @param remove igaz esetén törli az előző adatokat
     * @param columnsCount oszlopszám
     * @throws java.io.IOException kivétel
     */
    public ServerHoles(String workingDir, boolean remove, int columnsCount) throws IOException {
        this.workingDir = workingDir;
        this.columnsCount = columnsCount;

        // Ha nem létezik a munkakönyvtár akkor létrehozzuk.
        Path wp = Paths.get(this.workingDir);
        if (!Files.exists(wp)) {
            Files.createDirectory(wp);
        }

        // Ha van már tárolt adat és nem kell törölni az előző adatokat...
        if (Files.exists(Paths.get(this.workingDir + "/_")) && !remove) {
            // ...akkor a meglévőt fogjuk használni.
            JSONObject json = JSONUtils.JSONFromFile(this.workingDir + "/_");
            this.columnsCount = ((Long) json.get("cc")).intValue();
            return;
        } else {
            // Egyébként töröljük az előző munkamenetet.
            FileUtils.cleanDirectory(new File(this.workingDir));
        }

        // Adatok tárolása.
        JSONObject json = new JSONObject();
        json.put("cc", columnsCount);
        JSONUtils.JSONToFile(json, this.workingDir + "/_");
    }

    /**
     * Lyuk tárolása.
     *
     * @param bhd lyuk
     * @throws java.io.IOException kivétel
     */
    public void storeHole(BasicMotorHoleData bhd) throws IOException {
        if (null == bhd) {
            return;
        }

        Path wp = Paths.get(this.workingDir + "/" + bhd.holePosition[0] + "_" + bhd.holePosition[1]);
        JSONUtils.basicServerHoleDataToFile(wp, bhd);
    }

    /**
     * Letapogatott lyuk adatainak a lekérdezése.
     *
     * @param index lyuk sorszáma
     * @return lyuk adatai
     */
    public BasicMotorHoleData getHole(long index) {
        BasicMotorHoleData bhd = new BasicMotorHoleData();

        // Ha nincsenek adatok, akkor nem küldünk vissza semmit.
        if (!(0 < columnsCount)) {
            return null;
        }

        // Koordináták meghatározása.
        int x = (int) (index % (long) columnsCount) + 1;
        int y = (int) (Math.floor((double) index / (double) columnsCount)) + 1;

        // Páros sor esetén, visszafelé kérjük le az oszlopot (így letapogatás közben is minden lyukat megjeleníthetünk).
        if (0 == y % 2) {
            x = columnsCount - x + 1;
        }

        // Ha létezik a fájl, akkor küldjük a tartalmát.
        String fileName = this.workingDir + "/" + x + "_" + y;
        try {
            // Adatok beolvasása.
            JSONObject o = JSONUtils.JSONFromFile(fileName);
            bhd.holePosition[0] = ((Long) o.get("x")).intValue();
            bhd.holePosition[1] = ((Long) o.get("y")).intValue();
            bhd.motorPosition[0] = (Long) o.get("mx");
            bhd.motorPosition[1] = (Long) o.get("my");
        } catch (FileNotFoundException ex) {
            // Ha nincs ilyen fájl, akkor nem küldünk vissza semmit.
            return null;
        }

        return bhd;
    }

    /**
     * Oszlopok számának a lekérdezése.
     *
     * @return oszlopok száma
     */
    public int getColumnsCount() {
        return columnsCount;
    }
}
